﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;

namespace Fusion.Data.Contract
{
    public sealed class EntityInstance
    {
        private static volatile IEntityProvider instance = null;
        private static object syncRoot = new Object();

        private EntityInstance() { }

        public static IEntityProvider Instance
        {
            get
            {
                if (instance == null)
                {
                    lock (syncRoot)
                    {
                        if (instance == null)
                        {
                            Console.WriteLine("instance is null, creating new one");
                            Assembly library;
                            string filename = AppDomain.CurrentDomain.BaseDirectory + "Fusion.Data.dll";
                            string debugFilename = AppDomain.CurrentDomain.BaseDirectory + "Fusion.Data.pdb";

                            FileStream fs = File.Open(filename, FileMode.Open);
                            MemoryStream ms = new MemoryStream();
                            byte[] buffer = new byte[1024];
                            int read = 0;
                            while ((read = fs.Read(buffer, 0, 1024)) > 0)
                                ms.Write(buffer, 0, read);

                            FileStream fsd = File.Open(debugFilename, FileMode.Open);
                            MemoryStream msd = new MemoryStream();
                            byte[] bufferd = new byte[1024];
                            read = 0;
                            while ((read = fsd.Read(bufferd, 0, 1024)) > 0)
                                msd.Write(bufferd, 0, read);

                            library = Assembly.Load(ms.ToArray(), msd.ToArray());

                            fs.Close(); ms.Close();
                            fsd.Close(); msd.Close();


                            foreach (Type type in library.GetExportedTypes())
                            {
                                if (type.GetInterface("IEntityProvider") != null)
                                {
                                    instance = Activator.CreateInstance(type) as IEntityProvider;
                                    break;
                                }
                            }
                            if (instance == null)
                                throw new Exception("no class found that dll " + filename + " implements interface IEntityProvider");
                        }
                        else
                        {
                            Console.WriteLine("instance is not null, retuning old one");                        
                        }
                    }
                }

               return instance;
            }
        }
    }
}

/*
             Assembly library;
            string filename = @"D:\Projects\Fusion.Data.Generation.Test\Fusion.Data.Generation.Test\bin\Debug\Fusion.Data.dll";
            string debugFilename = @"D:\Projects\Fusion.Data.Generation.Test\Fusion.Data.Generation.Test\bin\Debug\Fusion.Data.pdb";

            FileStream fs = File.Open(filename, FileMode.Open);
            MemoryStream ms = new MemoryStream();
            byte[] buffer = new byte[1024];
            int read = 0;
            while ((read = fs.Read(buffer, 0, 1024)) > 0)
                ms.Write(buffer, 0, read);

            FileStream fsd = File.Open(debugFilename, FileMode.Open);
            MemoryStream msd = new MemoryStream();
            byte[] bufferd = new byte[1024];
            read = 0;
            while ((read = fsd.Read(bufferd, 0, 1024)) > 0)
                ms.Write(bufferd, 0, read);


            library = Assembly.Load(ms.ToArray(), msd.ToArray());

            fs.Close();
            ms.Close();

            fsd.Close();
            msd.Close();


            foreach (Type type in library.GetExportedTypes())
            {
                if (type.GetInterface("IEntityProvider") != null)
                    return Activator.CreateInstance(type) as IEntityProvider;
            }

            throw new Exception("no class found that implements interface IClass1");
 */